﻿using LxBasic;
using LxCore;

namespace LxCore
{
    public class ConnectWallTwoSide : ConnectWallBase
    {
        protected IField<double> ThermalResistance;//单位面积的热阻
        //protected double[] A24;
        //protected double[] A31;
        (double a21, double a24, double b2, double a31, double a34, double b3)[] Factors;
        public override void CheckCreate(FvJoint joint)
        {
            base.CheckCreate(joint);
            CheckCreator.ArrayStrict(ref Factors, ConFaces.Length);
            //CheckCreator.ArrayStrict(ref A31, Joints.Length);
        }
        public void SetConnect(EquationWithTransTerm OMatrix, EquationWithTransTerm NMatrix, IField<double> Source, IField<double> SourceDerivative, IField<double> thermalResistance)
        {
            setMatrix(OMatrix, NMatrix);
            this.Source_b = Source;
            this.Source_a = SourceDerivative;
            this.ThermalResistance = thermalResistance;
        }
        public override void FormAbOnFaces(ThreadInfo threadInfo)
        {
            var O_con = O_Matrix.GetConnectWallFactor(Joint.OBound);
            var N_con = N_Matrix.GetConnectWallFactor(Joint.NBound);
            (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
            var sou_b = Source_b.GetFaceVarArr(Joint);
            var sou_a = Source_a.GetFaceVarArr(Joint);
            var thermalResist = ThermalResistance.GetFaceVarArr(Joint);
            var osides = O_Matrix.Zone.BouFaces;

            for (; i1 < endp1; i1++)
            {
                ref FvJoiFace j = ref ConFaces[i1];
                double area = osides[j.O_BouFace].Area;
                double igg = area / thermalResist.GetFaceVar(i1);
                double s_a = area / 2 * sou_a.GetFaceVar(i1);
                double s_b = area / 2 * sou_b.GetFaceVar(i1);
                var ofactor = O_con.GetFactor(j.O_BouFace);
                var nfactor = N_con.GetFactor(j.N_BouFace);
                PairMatrix pm = new PairMatrix()
                {
                    a11 = ofactor.a11,
                    a12 = ofactor.a12,
                    b1 = ofactor.b1,
                    a21 = ofactor.a21,
                    a22 = ofactor.a22,
                    b2 = ofactor.b2,
                    a44 = nfactor.a11,
                    a43 = nfactor.a12,
                    b4 = nfactor.b1,
                    a34 = nfactor.a21,
                    a33 = nfactor.a22,
                    b3 = nfactor.b2,
                };
                pm.a22 += igg - s_a; pm.a23 = -igg; pm.b2 += s_b;
                pm.a32 = -igg; pm.a33 += igg - s_a; pm.b3 += s_b;
                pm.Eliminate_a23a32();
                pm.Eliminate_a12a43();
                O_con.SetFactor(j.O_BouFace, pm.a11, pm.b1);
                N_con.SetFactor(j.N_BouFace, pm.a44, pm.b4);
                A14[i1] = pm.a14;
                A41[i1] = pm.a41;
                this.Factors[i1] = (pm.a21 / pm.a22, pm.a24 / pm.a22, pm.b2 / pm.a22,
                    pm.a31 / pm.a33, pm.a34 / pm.a33, pm.b3 / pm.a33);

            }
        }

        public override void UpdateJointValue(ThreadInfo threadInfo)
        {

            (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
            for (; i1 < endp1; i1++)
            {
                ref var f = ref Factors[i1];
                ref FvJoiFace jf = ref ConFaces[i1];
                double x1 = O_XInn[jf.O_InnCell];
                double x4 = N_XInn[jf.N_InnCell];
                O_XBou[jf.O_BouFace] = f.b2
                        - f.a21 * x1
                        - f.a24 * x4;
                N_XBou[jf.N_BouFace] = f.b3
                    - f.a34 * x4
                    - f.a31 * x1;
            }
        }
    }
}
//var ofs = O_Matrix.FactorsToCalBouCell;
//var nfs = N_Matrix.FactorsToCalBouCell;
//if (Joint.IsConode)
//{
//    (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
//    for (; i1 < endp1; i1++)
//    {
//        ref FvJointFace jf = ref Joints[i1];
//        double x1 = O_XInn[jf.O_InnCell];
//        double x4 = N_XInn[jf.N_InnCell];
//        O_XInn[jf.O_BouFace] = ofs[jf.O_BouFace].b
//                - ofs[jf.O_BouFace].a * x1
//                - A24[i1] * x4;
//        N_XInn[jf.N_BouFace] = nfs[jf.N_BouFace].b
//            - nfs[jf.N_BouFace].a * x4
//            - A31[i1] * x1;
//    }

//}
//public override void FormAbOnJointFaces(ThreadInfo threadInfo)
//{
//    var O_Factors = O_Matrix.FactorsToCalBouCell;
//    double[] O_ABouO = O_Matrix.BouA;
//    double[] O_ABouN = O_Matrix.ABouNShare;
//    //double[] O_b = O_Matrix.B;
//    double[] O_bFaceCommon = O_Matrix.BouFaceShare;
//    var N_Factors = N_Matrix.FactorsToCalBouCell;
//    double[] N_ABouO = N_Matrix.BouA;
//    double[] N_ABouN = N_Matrix.ABouNShare;
//    //double[] N_b = N_Matrix.B;
//    double[] N_bFaceCommon = N_Matrix.BouFaceShare;
//    if (Joint.IsConode)
//    {
//        (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
//        var sou_b = Source_b.GetFaceVars(Joint);
//        var sou_a = Source_a.GetFaceVars(Joint);
//        var thermalResist = ThermalResistance.GetFaceVars(Joint);
//        var osides = O_Matrix.Zone.BouCFaces;
//        for (; i1 < endp1; i1++)
//        {
//            ref FvJointFace j = ref Joints[i1];
//            double area = osides[j.O_BouFace].Area;
//            double igg = area / thermalResist.GetFaceVar(i1);
//            double s_a = area / 2 * sou_a.GetFaceVar(i1);
//            double s_b = area / 2 * sou_b.GetFaceVar(i1);

//            ref double OA_bc = ref O_ABouN[j.O_BouFace];
//            ref double OA_bb = ref O_Factors[j.O_BouFace].a;
//            ref double OB_b = ref O_Factors[j.O_BouFace].b;

//            ref double NA_bc = ref N_ABouN[j.N_BouFace];
//            ref double NA_bb = ref N_Factors[j.N_BouFace].a;
//            ref double NB_b = ref N_Factors[j.N_BouFace].b;
//            PairMatrix pm = new PairMatrix();
//            pm.a12 = O_ABouO[j.O_BouFace]; pm.a11 = -OA_bc;
//            pm.a21 = OA_bc; pm.a22 = OA_bb + igg - s_a; pm.a23 = -igg; pm.b2 = OB_b + s_b;
//            pm.a32 = -igg; pm.a33 = NA_bb + igg - s_a; pm.a34 = NA_bc; pm.b3 = NB_b + s_b;
//            pm.a43 = N_ABouO[j.N_BouFace]; pm.a44 = -NA_bc;
//            pm.Eliminate_a23a32();
//            pm.Eliminate_a12a43();
//            A14[i1] = pm.a14;
//            A41[i1] = pm.a41;
//            A24[i1] = pm.a24 / pm.a22;
//            A31[i1] = pm.a31 / pm.a33;
//            OA_bc = -pm.a11;
//            O_bFaceCommon[j.O_BouFace] += pm.b1;
//            NA_bc = -pm.a44;
//            N_bFaceCommon[j.N_BouFace] += pm.b4;
//            OA_bb = pm.a21 / pm.a22;
//            OB_b = pm.b2 / pm.a22;
//            NA_bb = pm.a34 / pm.a33;
//            NB_b = pm.b3 / pm.a33;
//        }
//    }

//}